package com.zbec.mdrs.service;

import com.zbec.framework.core.service.SystemDictionaryService;
import com.zbec.framework.core.util.PageUtils;
import com.zbec.framework.core.vo.JqgridResponse;
import com.zbec.framework.core.vo.PageInfo;
import com.zbec.framework.security.entity.SysOrganization;
import com.zbec.framework.security.service.SecurityService;
import com.zbec.mdrs.constants.Constants;
import com.zbec.mdrs.entity.discount.Discount;
import com.zbec.mdrs.repository.jpa.DiscountDao;
import com.zbec.mdrs.util.DateUtils;
import com.zbec.mdrs.util.FilterUtils;
import com.zbec.mdrs.util.ResourceUtils;
import com.zbec.mdrs.util.ValidationUtils;
import com.zbec.mdrs.vo.DiscountVo;
import com.zbec.mdrs.vo.FilterSearch;
import com.zbec.mdrs.vo.SearchRuleVo;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springside.modules.mapper.JsonMapper;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;


/**
 * Created by fxl on 2015/10/19.
 */
@Component
@Transactional
public class DiscountService {
    @Autowired
    private DiscountDao discountDao;

    @Autowired
    private LogsService logsService;

    @Autowired
    private SystemDictionaryService systemDictionaryService;

    @Autowired
    private SecurityService securityService;

    @Autowired
    private ValidationService validationService;

    public JqgridResponse<DiscountVo> findAllDiscount(DiscountVo vo,PageInfo pageInfo) {
        if(vo.getSkipInd()!= null && "Y".equals(vo.getSkipInd())){
            vo.setRecordStatus(Constants.RECORD_STATUS_ADDEDSKIPED);
        }else {
            vo.setRecordStatus(Constants.RECORD_STATUS_ADDED);
        }
        if(vo.getQuery_sjsj()!=null && vo.getQuery_sjsj()!=""){
            vo.setSjsj(vo.getQuery_sjsj().replace("-",""));
        }
        vo.setExistError(vo.getQuery_existError());

        FilterSearch search=  JsonMapper.nonDefaultMapper().fromJson(vo.getFilters(), FilterSearch.class);

        Specification<Discount> spec = buildSpecification(vo,search);
        List<DiscountVo> discountVos=new ArrayList<DiscountVo>();
        Page<Discount>  discountVoPage= discountDao.findAll(spec, PageUtils.buildPageRequest(pageInfo));
        List<Discount> list=discountVoPage.getContent();
        for (int i = 0; i <list.size(); i++) {
            discountVos.add(convertDiscount2VO(list.get(i)));
        }
        return  PageUtils.buildResponse(discountVoPage,discountVos);

    }

    private Specification<Discount> buildSpecification(DiscountVo vo,FilterSearch search) {
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if(!StringUtils.isEmpty(vo.getRecordStatus())){
            filters.put("recordStatus", new SearchFilter("recordStatus", SearchFilter.Operator.EQ, vo.getRecordStatus()));
        }
        if(!StringUtils.isEmpty(vo.getOrgId())){
            filters.put("orgId", new SearchFilter("orgId", Operator.EQ, vo.getOrgId()));
        }
        if(!StringUtils.isEmpty(vo.getSjsj())){
            filters.put("sjsj", new SearchFilter("sjsj", Operator.EQ, vo.getSjsj()));
        }
        if(!StringUtils.isEmpty(vo.getExistError())){
            filters.put("existError", new SearchFilter("existError", Operator.EQ, vo.getExistError()));
        }

        if(vo.getSearch().equals("true")){
            List<SearchRuleVo> ruleList=search.getRules();
            for (int i = 0; i <ruleList.size(); i++) {
                SearchRuleVo rule=ruleList.get(i);
                if(rule.getField().equals("pjzl")){
                    String pjzl= systemDictionaryService.getSystemDictionaryValue(Constants.Constants_PJZL,rule.getData());
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), Operator.EQ, pjzl));
                }else if(rule.getField().equals("cdhdq")){
                    String cdhdq= systemDictionaryService.getSystemDictionaryValue(Constants.Constants_CDHDQ,rule.getData());
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), Operator.EQ, cdhdq));
                }else  if(rule.getField().equals("wjfl")){
                    String wjfl= systemDictionaryService.getSystemDictionaryValue(Constants.Constants_WJFL,rule.getData());
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), Operator.EQ, wjfl));
                }else  if(rule.getField().equals("txrq") || rule.getField().equals("cdrq")){
                    try {
                        filters.put(rule.getField(), new SearchFilter(rule.getField(), FilterUtils.getOperator(rule.getOp()), DateUtils.parseDate(rule.getData(), "yyyy-MM-dd") ));
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }

                }
                else{
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), FilterUtils.getOperator(rule.getOp()), rule.getData()));
                }
            }
        }
        
        Specification<Discount> spec = DynamicSpecifications.bySearchFilter(filters.values(), Discount.class);
        return spec;
    }

    public DiscountVo  convertDiscount2VO(Discount entity){
        DiscountVo discountVo = new DiscountVo();
        BeanUtils.copyProperties(entity, discountVo, new String[]{"history"});
        String  bzDesc=systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_BZ, discountVo.getBz());
        discountVo.setBzDesc(bzDesc==null?"":bzDesc);
        String wjflDesc=systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_WJFL, discountVo.getWjfl());
        discountVo.setWjflDesc(wjflDesc==null?"":wjflDesc);
        String  pjzlDesc=systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_PJZL, discountVo.getPjzl());
        discountVo.setPjzlDesc(pjzlDesc==null?"":pjzlDesc);
        String cdhdqDesc=systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_CDHDQ, discountVo.getCdhdq());
        discountVo.setCdhdqDesc(cdhdqDesc==null?"":cdhdqDesc);
        return discountVo;
    }


    public void  packagingBean(List<DiscountVo> list){
        for (int i = 0; i <list.size() ; i++) {
            DiscountVo discountVo=list.get(i);
            discountVo.setBzDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_BZ,discountVo.getBz()));
            discountVo.setWjflDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_WJFL, discountVo.getWjfl()));
            discountVo.setPjzlDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_PJZL, discountVo.getPjzl()));
            discountVo.setCdhdqDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_CDHDQ, discountVo.getCdhdq()));
        }
    }

    public JqgridResponse<DiscountVo> findDiscountByHistroy(String historyId,PageInfo pageInfo){
        Page<DiscountVo>  discountVoPage= discountDao.findDiscountByHistroy(historyId, PageUtils.buildPageRequest(pageInfo));
        packagingBean(discountVoPage.getContent());
        return PageUtils.buildResponse(discountVoPage, discountVoPage.getContent());
    }


    public void  addDiscount(DiscountVo discountVo){
        SysOrganization organization=securityService.getOrganizationByOrgId(discountVo.getOrgId());
        Discount discount=new Discount();
        BeanUtils.copyProperties(discountVo,discount);
        if(discount.getRecordStatus() == null ||"".equals(discount.getRecordStatus())){
            discount.setRecordStatus(Constants.RECORD_STATUS_ADDED);
        }
        discount.setReportStatus(Constants.REPORT_STATUS_ACTIVE);
        discount.setSource(Constants.SOURCE_DRMAP);
        discount.setJrjgwdmc(organization.getOrgName());
        discount.setWdssqu(organization.getField02());
        discount.setJrjgbm(organization.getOrgCode());
        validationService.validDiscount(discount);
        if(!StringUtils.isEmpty(discount.getErrorDesc())){
            discount.setExistError(Constants.EXIST_ERROR_YES);
        }else{
            discount.setExistError(Constants.EXIST_ERROR_NO);
        }
//        ValidationUtils.validateData(Constants.BUSINESS_TYPE_DISCOUNT, discount);
        discountDao.save(discount);
    }

    public void  updateLoan(DiscountVo discountVo,String userIp){

        Discount discount= discountDao.findOne(discountVo.getId());
        discount.setZzjgdm(discountVo.getZzjgdm());
        discount.setTxsqrmc(discountVo.getTxsqrmc());
        discount.setZsmy(discountVo.getZsmy());
        discount.setZsrmb(discountVo.getZsrmb());
        discount.setTxll(discountVo.getTxll());
        discount.setCdhdq(discountVo.getCdhdq());
        discount.setAdd(false);
        discount.setErrorDesc("");
        validationService.validDiscount(discount);
        if(!StringUtils.isEmpty(discount.getErrorDesc())){
            discount.setExistError(Constants.EXIST_ERROR_YES);
        }else{
            discount.setExistError(Constants.EXIST_ERROR_NO);
        }
        //ValidationUtils.validateData(Constants.BUSINESS_TYPE_DISCOUNT, discount);

        logsService.handleBuzLogData(userIp,"logs.type.24","logs.operation.update",true, ResourceUtils.getLocaleString("logs.24.update"));
    }

    public void ignoreDiscount(String ids){

        if(ids.length()>0){
            String [] idArray=ids.split(",");
            for (int i = 0; i < idArray.length; i++) {
                Discount discount= discountDao.findOne(Long.valueOf(idArray[i]));
                if(discount.getRecordStatus().equals(Constants.RECORD_STATUS_ADDED)){
                    discount.setRecordStatus(Constants.RECORD_STATUS_ADDEDSKIPED);
                }else{
                    discount.setRecordStatus(Constants.RECORD_STATUS_ADDED);
                }
            }

        }

    }

    public List<Discount> getActiveDiscountByYwMonth(final  String sjsj,final Long orgId) {
        List<Discount> list=discountDao.findAll(new Specification<Discount> (){
            @Override
            public Predicate toPredicate(Root<Discount> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicate = new ArrayList<>();
                predicate.add(cb.equal(root.get("sjsj"), sjsj));
                predicate.add(cb.equal(root.get("recordStatus"),Constants.RECORD_STATUS_ADDED));
                predicate.add(cb.notEqual(root.get("reportStatus"), Constants.REPORT_STATUS_COMPLETED));
                if(orgId!=null){
                    predicate.add(cb.equal(root.get("orgId"),orgId));
                }
                Predicate[] pre = new Predicate[predicate.size()];
                return query.where(predicate.toArray(pre)).getRestriction();
            }
        });
        return list;
    }

    public String importUpdate(MultipartFile file, String sjsj,String userIp) {
        sjsj=sjsj.replace("-", "");
        String[] columns = new String[Constants.IMPORT_FIELDS_DISCOUNT.size()];

        String message="";
        Boolean r2003 = false;
        Boolean r2007 = false;

        try {
            HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
            HSSFSheet sheet = wb.getSheetAt(0);
            int coloumNum=sheet.getRow(0).getPhysicalNumberOfCells();
            if(Constants.IMPORT_FIELDS_DISCOUNT.size()!=coloumNum)
            {
                return "false";
            }
            int total=sheet.getLastRowNum();
            message="导入"+total+"条.===";
            int m=0;
            for (int i = 0; i <= sheet.getLastRowNum(); i++) {
                HSSFRow row = sheet.getRow(i);
                if (i == 0) {
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        columns[j] = row.getCell(j).getStringCellValue();
                    }
                } else {

                    String[] values = new String[Constants.IMPORT_FIELDS_DISCOUNT.size()];
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        values[j] = row.getCell(j) == null ? "" : row.getCell(j).toString();
                    }

//                    Criterion key = Restrictions.eq(Constants.IMPORT_FIELDS_LOAN.get(columns[0]), values[0]);
//                    Criterion fny = Restrictions.eq("fny", yearmonth);
//                    Criterion status = Restrictions.ne("recordStatus", String.valueOf(3));
                    List<Discount> discounts = discountDao.findUpdateDiscount(values[0], sjsj, String.valueOf(3));
                    if (discounts != null && discounts.size() > 0) {
                        m=m+1;
                        for (Discount discount : discounts) {
                            for (int k = 1; k < columns.length; k++) {
                                try {
                                    Object o = PropertyUtils.getProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]));
//                                    if ((o == null || "".equals(o)) && values[k] != null && !"".equals(values[k])) {
                                    if (values[k] != null && !"".equals(values[k])) {
                                        Class c = PropertyUtils.getPropertyType(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]));
                                        if (c == BigDecimal.class) {
                                            PropertyUtils.setProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]), new BigDecimal(values[k]));
                                        } else if (c == Date.class) {
                                            PropertyUtils.setProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]), DateUtils.parseDate(values[k], "yyyy/MM/dd"));
                                        } else {
                                            PropertyUtils.setProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]), values[k]);
                                        }
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                            ValidationUtils.validateData(Constants.BUSINESS_TYPE_DISCOUNT, discount);

                            discountDao.save(discount);
                        }
                    }

                }
            }
            message=message+"匹配"+m+"条.===";
            if(m==0){
                message=message+"匹配率0%===";
            }else{
                double tempresult=(double)m/(double)total;
                DecimalFormat df1 = new DecimalFormat("0.00%"); ;
                message=message+"匹配率"+df1.format(tempresult)+"===";
            }
            r2003 = true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            if(!r2003) {
                XSSFWorkbook wb = new XSSFWorkbook(file.getInputStream());
                XSSFSheet sheet = wb.getSheetAt(0);
                int coloumNum=sheet.getRow(0).getPhysicalNumberOfCells();
                if(Constants.IMPORT_FIELDS_DISCOUNT.size()!=coloumNum)
                {
                    return "false";
                }
                int total=sheet.getLastRowNum();
                message="导入"+total+"条.===";
                int m=0;
                for (int i = 0; i <= sheet.getLastRowNum(); i++) {
                    XSSFRow row = sheet.getRow(i);
                    if (i == 0) {
                        for (int j = 0; j < row.getLastCellNum(); j++) {
                            columns[j] = row.getCell(j).getStringCellValue();
                        }
                    } else {

                        String[] values = new String[Constants.IMPORT_FIELDS_DISCOUNT.size()];
                        for (int j = 0; j < row.getLastCellNum(); j++) {
                            values[j] = row.getCell(j) == null ? "" : row.getCell(j).toString();
                        }

//                    Criterion key = Restrictions.eq(Constants.IMPORT_FIELDS_LOAN.get(columns[0]), values[0]);
//                    Criterion fny = Restrictions.eq("fny", yearmonth);
//                    Criterion status = Restrictions.ne("recordStatus", String.valueOf(3));
                        List<Discount> discounts = discountDao.findUpdateDiscount(values[0], sjsj, String.valueOf(3));
                        if (discounts != null && discounts.size() > 0) {
                            m=m+1;
                            for (Discount discount : discounts) {
                                for (int k = 1; k < columns.length; k++) {
                                    try {
                                        Object o = PropertyUtils.getProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]));
//                                    if ((o == null || "".equals(o)) && values[k] != null && !"".equals(values[k])) {
                                        if (values[k] != null && !"".equals(values[k])) {
                                            Class c = PropertyUtils.getPropertyType(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]));
                                            if (c == BigDecimal.class) {
                                                PropertyUtils.setProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]), new BigDecimal(values[k]));
                                            } else if (c == Date.class) {
                                                PropertyUtils.setProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]), DateUtils.parseDate(values[k], "yyyy/MM/dd"));
                                            } else {
                                                PropertyUtils.setProperty(discount, Constants.IMPORT_FIELDS_DISCOUNT.get(columns[k]), values[k]);
                                            }
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                                ValidationUtils.validateData(Constants.BUSINESS_TYPE_DISCOUNT, discount);

                                discountDao.save(discount);
                            }
                        }

                    }
                }
                message=message+"匹配"+m+"条.===";
                if(m==0){
                    message=message+"匹配率0%===";
                }else{
                    double tempresult=(double)m/(double)total;
                    DecimalFormat df1 = new DecimalFormat("0.00%"); ;
                    message=message+"匹配率"+df1.format(tempresult)+"===";
                }
                r2007 = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(r2003||r2007){
            logsService.handleBuzLogData(userIp,"logs.type.24","logs.operation.importUpdate",true,ResourceUtils.getLocaleString("message.importsuccess"));
            return message;
        }else{
            return "false";
        }
    }


}
